package com.alibaba.citrus.ots.platform.enhance.repository.impl;

import com.alibaba.citrus.ots.common.annotation.RepositoryInvoker;
import com.alibaba.citrus.ots.common.util.DateUtils;
import com.alibaba.citrus.ots.platform.enhance.functions.utils.ConverterUtils;
import com.alibaba.citrus.ots.platform.enhance.repository.StrategyQueryRepository;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.epoch.app.bcots.model.dto.BaselineBatchQueryChannelsRequest;
import com.epoch.app.bcots.model.dto.QueryWarehouseByIdRequest;
import com.epoch.app.bcots.model.dto.WarehouseInfo;
import com.epoch.app.bcots.service.BaseDataService;
import com.epoch.app.bcots.service.UnifiedInventoryService;
import com.epoch.app.otsplatformenhance.api.organizationquery.service.OrganizationQueryService;
import com.epoch.app.otsplatformenhance.channel.service.ChannelService;
import com.epoch.app.otsplatformenhance.dimension.model.Dimension;
import com.epoch.app.otsplatformenhance.dimension.service.DimensionService;
import com.epoch.app.otsplatformenhance.dto.request.IdQueryRequest;
import com.epoch.app.otsplatformenhance.enums.DimensionTypeEnum;
import com.epoch.app.otsplatformenhance.enums.RoleCodeEnum;
import com.epoch.app.otsplatformenhance.enums.StrategyTypeEnum;
import com.epoch.app.otsplatformenhance.model.dto.*;
import com.epoch.app.otsplatformenhance.model.enums.StatusEnum;
import com.epoch.app.otsplatformenhance.sdo.DimensionSDO;
import com.epoch.app.otsplatformenhance.sdo.OrganizationSDO;
import com.epoch.app.otsplatformenhance.sdo.StrategySDO;
import com.epoch.app.otsplatformenhance.strategy.dto.*;
import com.epoch.app.otsplatformenhance.strategy.model.Strategy;
import com.epoch.app.otsplatformenhance.strategy.service.StrategyService;
import org.apache.commons.collections.MapUtils;
import org.apache.velocity.runtime.directive.Break;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

@Component
public class StrategyQueryRepositoryImpl implements StrategyQueryRepository {

    @Resource
    private StrategyService strategyService;

    @Resource
    private DimensionService dimensionService;

    @Resource
    private ChannelService channelService;

    @Resource
    private UnifiedInventoryService unifiedInventoryService;

    @Resource
    private OrganizationQueryService organizationQueryService;

    @Override
    public Result<List<StrategyPageQueryResponse>> pageQuery(StrategyPageQueryRequest request) {
        StrategyLoadListRequest strategyLoadListRequest = ConverterUtils.pageQueryConverter(request);
        Result<List<Strategy>> listResult = strategyService.loadStrategyList(strategyLoadListRequest);
        if (CollectionUtils.isEmpty(listResult.getResult())) {
            return new Result<>();
        }
        List<StrategyPageQueryResponse> queryResponses = listResult.getResult().stream().map(ConverterUtils::pageQueryResponseConverter)
                .collect(Collectors.toList());
        if (StrategyTypeEnum.INVENTORY_ROUTING.getCode().equals(request.getType())){
            for(StrategyPageQueryResponse strategyPageQueryResponse:queryResponses){
                StatusDesc statusDesc = new StatusDesc();
                if ("1".equals(strategyPageQueryResponse.getStatus())) {
                    statusDesc.setText("已开启");
                    statusDesc.setValue(true);
                } else if ("0".equals(strategyPageQueryResponse.getStatus())) {
                    statusDesc.setText("已关闭");
                    statusDesc.setValue(false);
                }
                strategyPageQueryResponse.setStatusDesc(statusDesc);
            }
        }
        return Result.listSuccess(queryResponses, listResult.getTotal());
    }


    @Override
    @RepositoryInvoker
    public Result<StrategyQueryByIdResponse> queryById(StrategyQueryByIdRequest request) {
        StrategyQueryByIdResponse strategyQueryByIdResponse = new StrategyQueryByIdResponse();
        int total = 0;
        if (null != request.getId()) {
            LoadStrategyRequest loadStrategyRequest = new LoadStrategyRequest();
            loadStrategyRequest.setId(request.getId());
            Strategy strategy = strategyService.loadStrategy(loadStrategyRequest);
            if (null != strategy) {
                StrategySDO strategySDO = strategySDOConverter(strategy);
                if (null != strategy.getId()) {
                    DimensionLoadListRequest dimensionLoadListRequest = new DimensionLoadListRequest();
                    dimensionLoadListRequest.setStrategyId(String.valueOf(strategy.getId()));
                    dimensionLoadListRequest.setCode(request.getCode());
                    dimensionLoadListRequest.setStatus(request.getStatus());
                    dimensionLoadListRequest.setLimit(999);
                    Result<List<Dimension>> listResult = dimensionService.loadDimensionList(dimensionLoadListRequest);
                    if (!CollectionUtils.isEmpty(listResult.getResult())) {
                        List<DimensionSDO> dimensionSDOS = listResult.getResult().stream().map(dimension -> {
                            DimensionSDO dimensionSDO = dimensionSDOConverter(dimension,strategy.getType());
                            return dimensionSDO;
                        }).collect(Collectors.toList());
                        //维度根据优先级排序，值越小优先级越高 add my wangzq for MN-4131
                        dimensionSDOS = dimensionSDOS.stream().sorted(Comparator.comparing(DimensionSDO::getPriority,Comparator.nullsFirst(Comparator.naturalOrder()))).collect(Collectors.toList());
                        strategySDO.setDimensionSDOList(dimensionSDOS);
                        total = dimensionSDOS.size();
                    }
                    strategyQueryByIdResponse.setStrategySDO(strategySDO);
                }
            }
            Result<StrategyQueryByIdResponse> result = Result.success(strategyQueryByIdResponse);
            result.setTotal(total);
            return result;
        }
        return Result.success(null);
    }

    @Override
    public Result<MoreConditionQueryResponse> moreConditionQuery(MoreConditionQueryRequest request, Map<String, String> codeAndValue) {
        StrategyLoadListRequest query = strategyLoadListRequestConverter(request);
        Result<List<Strategy>> listResult = strategyService.loadStrategyList(query);
        if (CollectionUtils.isEmpty(listResult.getResult())) {
            return new Result<>();
        }
//        List<Strategy> strategies = new ArrayList<>();
        //判断策略类型 如果是有效期的不走主单时间校验
//        if(!request.getStrategyType().equals("1")) {
//            for (int i = 0; i < listResult.getResult().size(); i++) {
//                if (listResult.getResult().get(i).getValidBeginTime() != null) {
//                    if (listResult.getResult().get(i).getValidBeginTime().before(new Date()) && listResult.getResult().get(i).getValidEndTime().after(new Date())) {
//                        strategies.add(listResult.getResult().get(i));
//                    }
//                }
//
//            }
//        }else{
//            for (int i = 0; i < listResult.getResult().size(); i++) {
//                strategies.add(listResult.getResult().get(i));
//            }
//        }

        List<Dimension> dimensionList = new ArrayList<>();
        for (Strategy strategy : listResult.getResult()) {
            if (null != strategy.getId()) {
                DimensionLoadListRequest dimensionLoadListRequest = new DimensionLoadListRequest();
                dimensionLoadListRequest.setStrategyId(String.valueOf(strategy.getId()));
//              if(request.getStrategyType().equals("1")) {
//               }
                dimensionLoadListRequest.setStatus(StatusEnum.open.getCode());
                Result<List<Dimension>> result = dimensionService.loadDimensionList(dimensionLoadListRequest);
                if (!CollectionUtils.isEmpty(result.getResult())) {
                    List<Dimension> result1 = result.getResult();
                    for (Dimension dimension : result1) {
                        if (dimension.getValidBeginTime().before(new Date()) && dimension.getValidEndTime().after(new Date())) {
                            dimensionList.add(dimension);
                        }
                    }

                }

            }
        }
        String departmentCode = null;
        String channelCode = null;
        String customerCode = null;
        String wareHouseCode = null;
        List<Dimension> dimensions = new ArrayList<>();
        if (!MapUtils.isEmpty(codeAndValue)) {
            for (String key : codeAndValue.keySet()) {
                if (DimensionTypeEnum.DEPARTMENT.getCode().equals(key)) {
                    departmentCode = codeAndValue.get(key);
                }
                if (DimensionTypeEnum.CHANNEL.getCode().equals(key)) {
                    channelCode = codeAndValue.get(key);
                }
                if (DimensionTypeEnum.CUSTOMER.getCode().equals(key)) {
                    customerCode = codeAndValue.get(key);
                }
                if (DimensionTypeEnum.STORE_ROOM.getCode().equals(key)) {
                    wareHouseCode = codeAndValue.get(key);
                }
            }
        }
        String finalDepartmentCode = departmentCode;
        String finalChannelCode = channelCode;
        String finalCustomerCode = customerCode;
        String finalWareHouseCode = wareHouseCode;

        List<Dimension> dimensionsOne = new ArrayList<>();
        dimensionList.stream().forEach(x -> {
            if (x.getValue() != null) {
                if (x.getValue().equals(finalDepartmentCode)) {
                    dimensionsOne.add(x);
                    return;
                }
                if (x.getValue().equals(finalChannelCode)) {
                    dimensionsOne.add(x);
                    return;
                }
                if (x.getValue().equals(finalCustomerCode)) {
                    dimensionsOne.add(x);
                    return;
                }
                if (x.getValue().equals(finalWareHouseCode)) {
                    dimensionsOne.add(x);
                    return;
                }
            }
        });
        if (dimensionsOne.size() == 0) {
            return Result.success(null);
        }
        Dimension dimension = dimensionsOne.get(0);
        MoreConditionQueryResponse moreConditionQueryResponse = new MoreConditionQueryResponse();
        List<DimensionSDO> dimensionSDOS = new ArrayList<>();
        StrategySDO strategySDO = new StrategySDO();
        DimensionSDO dimensionSDO = new DimensionSDO();
        BeanUtils.copyProperties(dimension,dimensionSDO);
        if (null != dimension.getExecuteAction()) {
            dimensionSDO.setExecuteAction(dimension.getExecuteAction());
        }
        dimensionSDOS.add(dimensionSDO);
        strategySDO.setDimensionSDOList(dimensionSDOS);
        moreConditionQueryResponse.setStrategySDO(strategySDO);
        return Result.success(moreConditionQueryResponse);
    }

    @Override
    public List<String> checkStrategy(CreateDailyInventoryRequest request) {
        QueryStrategyToCheckRequest qeueryRequest = new QueryStrategyToCheckRequest();
        qeueryRequest.setType(request.getType());
        qeueryRequest.setDimensionType(request.getDimensionType());
        qeueryRequest.setOrganizationCode(request.getOrganizationCode());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            List<String> strategyValid = request.getStrategyValid();
            Date begin = sdf.parse(strategyValid.get(0));
            Date end = sdf.parse(strategyValid.get(1));
            qeueryRequest.setValidBeginTime(begin);
            qeueryRequest.setValidEndTime(end);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        QueryStrategyToCheckResponse queryStrategyToCheckResponse = strategyService.queryStrategyToCheck(qeueryRequest);
        return queryStrategyToCheckResponse.getIds();
    }

    @Override
    public List<StrategySDO> queryStrategyList() {
        QueryStrategyListResponse queryStrategyListResponse = strategyService.queryStrategyList();
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(queryStrategyListResponse.getStrategys())) {
            List<StrategySDO> strategySDOS = new ArrayList<>();
            for (Strategy strategy : queryStrategyListResponse.getStrategys()) {
                StrategySDO strategySDO = strategySDOConverter(strategy);

                //查询子单
                DimensionLoadListRequest dimensionLoadListRequest = new DimensionLoadListRequest();
                dimensionLoadListRequest.setStrategyId(String.valueOf(strategy.getId()));
                Result<List<Dimension>> listResult = dimensionService.loadDimensionList(dimensionLoadListRequest);
                List<DimensionSDO> dimensionSDOS = listResult.getResult().stream().map(dimension -> {
                    DimensionSDO dimensionSDO = dimensionSDOConverter(dimension, strategySDO.getType());
                    return dimensionSDO;
                }).collect(Collectors.toList());
                strategySDO.setDimensionSDOList(dimensionSDOS);
                strategySDOS.add(strategySDO);
            }
            return strategySDOS;
        }
        return null;
    }

    @Override
    public List<StrategySDO> queryValidStrategyList(QueryValidStrategyListRequest queryValidStrategyListRequest) {
        QueryValidStrategyListResponse resp = strategyService.queryValidStrategyList(queryValidStrategyListRequest);
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(resp.getStrategys())) {
            List<StrategySDO> strategySDOS = new ArrayList<>();
            for (Strategy strategy : resp.getStrategys()) {
                StrategySDO strategySDO = strategySDOConverter(strategy);

                //查询子单
                DimensionLoadListRequest dimensionLoadListRequest = new DimensionLoadListRequest();
                dimensionLoadListRequest.setStrategyId(String.valueOf(strategy.getId()));
                dimensionLoadListRequest.setStart(0);
                dimensionLoadListRequest.setLimit(1000);
                Result<List<Dimension>> listResult = dimensionService.loadDimensionList(dimensionLoadListRequest);
                List<DimensionSDO> dimensionSDOS = listResult.getResult().stream().map(dimension -> {
                    DimensionSDO dimensionSDO = dimensionSDOConverter(dimension, strategySDO.getType());
                    return dimensionSDO;
                }).collect(Collectors.toList());
                strategySDO.setDimensionSDOList(dimensionSDOS);
                strategySDOS.add(strategySDO);
            }
            return strategySDOS;
        }
        return null;
    }


    private StrategyLoadListRequest strategyLoadListRequestConverter(MoreConditionQueryRequest request) {
        StrategyLoadListRequest strategyLoadListRequest = new StrategyLoadListRequest();
        if (!StringUtils.isEmpty(request.getOrganizationCode())) {
            strategyLoadListRequest.setOrganizationCode(request.getOrganizationCode());
        }
        if (!StringUtils.isEmpty(request.getStrategyType())) {
            strategyLoadListRequest.setType(request.getStrategyType());
        }
        strategyLoadListRequest.setAsc(false);
        strategyLoadListRequest.setStart(request.getStart());
        strategyLoadListRequest.setLimit(request.getLimit());
        strategyLoadListRequest.setDir("gmtCreate");
        return strategyLoadListRequest;
    }


    private DimensionSDO dimensionSDOConverter(Dimension dimension,String type) {
        DimensionSDO dimensionSDO = new DimensionSDO();
        dimensionSDO.setId(dimension.getId());
        dimensionSDO.setCode(dimension.getCode());
        if (!StringUtils.isEmpty(dimension.getCode())) {
            dimensionSDO.setCodeName(DimensionTypeEnum.of(dimension.getCode()).getDesc());
        }
        if (type.equals(StrategyTypeEnum.DAILY_INVENTORY.getCode()) || type.equals(StrategyTypeEnum.First_REPLY.getCode())) {
            dimensionSDO.setOutCode(dimension.getOutCode());
            dimensionSDO.setValue(dimension.getValue());
        } else {
            if (Objects.nonNull(dimension.getValue())) {
                if (DimensionTypeEnum.CHANNEL.getCode().equals(dimension.getCode())) {
                    QueryChannelRequest queryChannelRequest = new QueryChannelRequest();
                    queryChannelRequest.setChannelCode(dimension.getValue());
                    Result<ChannelResponse> channelResponseResult = channelService.queryChannelDetail(queryChannelRequest);
                    if (Objects.nonNull(channelResponseResult.getResult())&& !StringUtils.isEmpty(channelResponseResult.getResult().getChannelName())) {
                        dimensionSDO.setValueName(channelResponseResult.getResult().getChannelName());
                        dimensionSDO.setOutCode(channelResponseResult.getResult().getOutCode());
                    }

                } else if (DimensionTypeEnum.STORE_ROOM.getCode().equals(dimension.getCode())) {
                    QueryWarehouseByIdRequest queryWarehouseByIdRequest = new QueryWarehouseByIdRequest();
                    queryWarehouseByIdRequest.setId(dimension.getValue());
                    Result<WarehouseInfo> warehouseInfoResult = unifiedInventoryService.queryWarehouseById(queryWarehouseByIdRequest);
                    if (Objects.nonNull(warehouseInfoResult.getResult())) {
                        dimensionSDO.setValueName(warehouseInfoResult.getResult().getName());
                        dimensionSDO.setOutCode(warehouseInfoResult.getResult().getCode());
                    }
                } else if (DimensionTypeEnum.DEPARTMENT.getCode().equals(dimension.getCode())) {
                    IdQueryRequest idQueryRequest = new IdQueryRequest();
                    idQueryRequest.setId(dimension.getValue());
                    Result<OrganizationSDO> organizationDetail = organizationQueryService.getOrganizationDetail(idQueryRequest);
                    if (Objects.nonNull(organizationDetail.getResult())) {
                        dimensionSDO.setValueName(organizationDetail.getResult().getName());
                        dimensionSDO.setOutCode(organizationDetail.getResult().getOutCode());
                    }
                } else {
                    dimensionSDO.setValue(dimension.getValue());
                }

            }
        }
        dimensionSDO.setRuleName(dimension.getRuleName());
        dimensionSDO.setRuleValue(dimension.getRuleValue());
        dimensionSDO.setStatus(dimension.getStatus());
        StatusDesc statusDesc = new StatusDesc();
        if (StatusEnum.open.getCode().equals(dimension.getStatus())) {
            statusDesc.setText("已开启");
            statusDesc.setValue(true);
        } else if (StatusEnum.close.getCode().equals(dimension.getStatus())) {
            statusDesc.setText("已关闭");
            statusDesc.setValue(false);
        }
        dimensionSDO.setStatusDesc(statusDesc);
        dimensionSDO.setValidBeginTime(dimension.getValidBeginTime());
        dimensionSDO.setValidEndTime(dimension.getValidEndTime());
        dimensionSDO.setExecuteAction(dimension.getExecuteAction());
        ExecuteActionDesc executeActionDesc = new ExecuteActionDesc();
        if (dimension.getExecuteAction() != null) {
            if (dimension.getExecuteAction()) {
                executeActionDesc.setValue(true);
                executeActionDesc.setText("开启校验");
            } else {
                executeActionDesc.setValue(false);
                executeActionDesc.setText("关闭校验");
            }
        }
        dimensionSDO.setExecuteActionDesc(executeActionDesc);
        dimensionSDO.setStrategyId(dimension.getStrategyId());
        dimensionSDO.setDetails(dimension.getDetails());
        dimensionSDO.setCreator(dimension.getCreator());
        dimensionSDO.setUpdater(dimension.getUpdater());
        dimensionSDO.setGmtCreate(dimension.getGmt_create());
        dimensionSDO.setGmtModified(dimension.getGmt_modified());
        dimensionSDO.setPriority(dimension.getPriority());
        if (StringUtils.isEmpty(dimensionSDO.getValueName())) {
            dimensionSDO.setValueName(dimension.getValueName());
        }
        if (StrategyTypeEnum.INVENTORY_ROUTING.getCode().equals(type)) {
            dimensionSDO.setValue(dimension.getValue());
        }
        return dimensionSDO;
    }

    private StrategySDO strategySDOConverter(Strategy strategy) {
        StrategySDO strategySDO = new StrategySDO();
        if (null != strategy.getId()) {
            strategySDO.setId(String.valueOf(strategy.getId()));
        }

        strategySDO.setOrganizationCode(strategy.getOrganizationCode());
        strategySDO.setOrganizationName(strategy.getOrganizationName());
        strategySDO.setType(strategy.getType());
        strategySDO.setValidBeginTime(strategy.getValidBeginTime());
        strategySDO.setValidEndTime(strategy.getValidEndTime());
        List<String> timeList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat(DateUtils.DATETIME_FORMAT);
        if (strategy.getValidBeginTime() != null) {
            timeList.add(sdf.format(strategy.getValidBeginTime()));
        }
        if (strategy.getValidEndTime() != null) {
            timeList.add(sdf.format(strategy.getValidEndTime()));
        }
        strategySDO.setStrategyValid(timeList);
        strategySDO.setStatus(strategy.getStatus());
        strategySDO.setName(strategy.getName());
        strategySDO.setGmtCreate(strategy.getGmt_create());
        strategySDO.setGmtModified(strategy.getGmt_modified());
        strategySDO.setCreator(strategy.getCreator());
        strategySDO.setUpdater(strategy.getUpdater());
        strategySDO.setDimensionType(strategy.getDimensionType());
        strategySDO.setPriority(strategy.getPriority());
        strategySDO.setShare(strategy.getShare());
        strategySDO.setDailyEndTime(strategy.getDailyEndTime());
        strategySDO.setDailyBeginTime(strategy.getDailyBeginTime());
        if (null != strategy.getFeature() && org.apache.commons.lang3.StringUtils.isNotBlank(strategy.getFeature())) {
            Map<String, String> feature = (Map) JSONObject.parseObject(strategy.getFeature());
            strategySDO.setFeature(feature);
        }
        return strategySDO;
    }
}
